<?php
/**
 * User: Hufeng
 * Date: 2017/12/04 17:51
 * Desc: TRADE 交易SERVER
 */
namespace App\Controller;
use App\Model\NewsModel;
use App\Model\NewsTypeModel;
use App\Model\SelfStockModel;
use App\Model\StockCompanyModel;
use App\Model\StockHandicapModel;
use App\Model\StockModel;
use App\Model\StockNoticeModel;
use App\Model\TradeDealhistoryModel;
use App\Model\TradeDelegateHistoryModel;
use App\Model\TradeKlineModel;
use App\Model\TradePlaceModel;
use App\Common\Util\Redis;
use App\Model\TradeUserAssetModel;
use App\Model\UserAssetsModel;
use App\Common\Util\Task;
use App\Model\UserModel;
use App\Controller\Task as Stask;

class Trade extends Base {

    public function __construct(){
        parent::__construct();
    }

    //首页播报(股票名称，各股当前价格，涨跌价格，涨跌比例)
    public function broadCast(){
        $sModel = new StockModel();
        $sList = $sModel->queryData(['status'=>1]);
        $sData = [];
        foreach ($sList as $val){
            $sData[$val['id']]['sno'] = $val['stock_no'];
            $sData[$val['id']]['sname'] = $val['stock_name'];
        }
        $shModel = new StockHandicapModel();
        $shList = $shModel->queryData(['status'=>1]);
        $data = [];
        foreach ($shList as $val){
            $arr = [];
            $arr['name'] = $sData[$val['sid']]['sname'].'('.$sData[$val['sid']]['sno'].')';
            $yclosePrice = round($val['new_price']/(1+$val['zd_rang']/100),2);
            $price = $val['new_price'];
            $rangePrice = round($price-$yclosePrice,2);
            if($rangePrice>=0){
                $arr['rise'] = 1;
                $arr['price']=$price.'+'.$rangePrice.'+'.$val['zd_rang'].'%';
            }else{
                $arr['rise'] = 2;
                $arr['price']=$price.$rangePrice.$val['zd_rang'].'%';
            }
            $data[] = $arr;
        }
        $this->outData['data'] = $data;
        return $this->fjson($this->outData);
    }
    //首页新闻列表（取前5条数据）
    public function newsList(){
        $nModel = new NewsModel();
        $nlist = $nModel->queryData(['status'=>1,'ORDER'=>['sort'=>'DESC'],'LIMIT'=>5],['id','title','info','show_type','cover_img','laud_num','type_id']);
        $typeIdArr = [];
        foreach ($nlist as $val){
            $typeIdArr[] = $val['type_id'];
        }
        $typeArr = [];
        if($typeIdArr){
            $ntModel = new NewsTypeModel();
            $ntList = $ntModel->queryData(['id'=>$typeIdArr]);
            foreach ($ntList as $val){
                $typeArr[$val['id']] = $val['name'];
            }
        }
        foreach ($nlist as &$val){
            $val['type_name'] = $typeArr[$val['type_id']];
        }
        $this->outData['data'] = $nlist;
        return $this->fjson($this->outData);
    }
    //新闻详情
    public function newsInfo(){
        $needParam = array(
            'nid'=>array('msg'=>'nid参数异常','type'=>'int')
        );
        $this->regArguments($needParam,$this->param);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $nModel = new NewsModel();
        $nRes = $nModel->findData(['id'=>$this->param['nid'],'status'=>1]);
        //增加阅读数量
        $nModel->editData(['id'=>$this->param['nid']],['laud_num[+]'=>1]);
        $ntModel = new NewsTypeModel();
        $ntRes = $ntModel->findData(['id'=>$nRes['type_id']]);
        $nRes['type_name'] = $ntRes['name'];
        $this->outData['data'] = $nRes;
        return $this->fjson($this->outData);
    }
    //我的持仓(持仓总盈亏，总市值，今日盈亏，股票（名称,代码 涨跌比例，涨跌金额，现价，持仓，成本，市值）)
    public function myAssets(){
//        $this->param['openId'] = 'o21vjJEJjN61Nz';
//        $this->param['token'] = sha1(md5('o21vjJEJjN61Nzhje11shkeo479'));

        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'token'=>array('msg'=>'token参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        $this->regToken($this->param['token'],$this->param['openId']);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }
        $sModel = new StockModel();
        $tuaModel = new TradeUserAssetModel();
        $shModel = new StockHandicapModel();
        $tuaQuery = $tuaModel->queryData(['uid'=>$uid,'havenum[>]'=>0],['sid','avg_price','havenum']);
        $sidArr = [];
        foreach ($tuaQuery as $val){
            $sidArr[] = $val['sid'];
        }
        $shRes = $sRes = [];
        if($sidArr){
            $sQuery = $sModel->queryData(['id'=>$sidArr],['id','stock_no','stock_name']);
            foreach ($sQuery as $val){
                $sRes[$val['id']] = $val;
            }
            $shQuery = $shModel->queryData(['sid'=>$sidArr]);
            foreach ($shQuery as $val){
                $shRes[$val['sid']] = $val;
            }
        }
        $sData = [];
        $totalMoney = $totalChMoney = $todayMoney = 0;
        foreach ($tuaQuery as $val){
            $arr = [];
            $sid = $val['sid'];
            $arr['sid'] = $sid;
            $arr['sno'] = $sRes[$sid]['stock_no'];
            $arr['sname'] = $sRes[$sid]['stock_name'];
            $newPrice = $shRes[$sid]['update_time'] ? $shRes[$sid]['new_price'] : $val['avg_price'];
            $arr['chratio'] = (round(($newPrice-$val['avg_price'])/$val['avg_price'],2)*100).'%';
            $arr['chmoney'] = round($newPrice-$val['avg_price'],2);
            $arr['nowMoney'] = $newPrice;
            $arr['handNum'] = $val['havenum'];
            $arr['handPrice'] = $val['avg_price'];
            $arr['totalMoney'] = round($arr['nowMoney']*$arr['handNum'],2);
            $sData[] = $arr;
            $totalMoney += $arr['totalMoney'];
            $totalChMoney += $arr['chmoney'];
            //今日盈亏
            $ycMoney = round($newPrice/(1+($shRes[$sid]['zd_rang']/100)),2);
            $todayMoney = round($todayMoney+$newPrice-$ycMoney,2);
        }
        $this->outData['sData'] = $sData;
        $this->outData['cData'] = ['totalMoney'=>$totalMoney,'totalChMoney'=>$totalChMoney,'todayMoney'=>$todayMoney];
        return $this->fjson($this->outData);
    }

    //历史交易
    public function history(){
//        $this->param['openId'] = 'o21vjJEJjN61Nz';
//        $this->param['token'] = sha1(md5('o21vjJEJjN61Nzhje11shkeo479'));
//        $this->param['sdate'] = '2017-12-1';
//        $this->param['edate'] = '2018-12-1';
        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'sdate'=>array('msg'=>'sdate参数异常','type'=>'str'),
            'edate'=>array('msg'=>'edate参数异常','type'=>'str'),
            'token'=>array('msg'=>'token参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        $this->regToken($this->param['token'],$this->param['openId']);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }
        $this->param['sdate'] = date('Y-m-d H:i:s',strtotime($this->param['sdate']));
        $this->param['edate'] = date('Y-m-d H:i:s',strtotime($this->param['edate']));
        $tdhModel = new TradeDealhistoryModel();
        $tdhQuery = $tdhModel->queryData(['sale_uid'=>$uid,'addtime[>=]'=>$this->param['sdate'],'addtime[<=]'=>$this->param['edate']]);
        $sidArr = [];
        foreach ($tdhQuery as $val){
            $sidArr[] = $val['sid'];
        }
        $sModel = new StockModel();
        $sRes = [];
        if($sidArr){
            $sQuery = $sModel->queryData(['id'=>$sidArr],['id','stock_no','stock_name']);
            foreach ($sQuery as $val){
                $sRes[$val['id']] = $val;
            }
        }
        $list = [];
        foreach ($tdhQuery as $val){
            $sid = $val['sid'];
            $list[$sid]['sid'] = $sid;
            $list[$sid]['sno'] = $sRes[$sid]['stock_no'];
            $list[$sid]['sname'] = $sRes[$sid]['stock_name'];
            if(!isset($list[$sid]['sdate'])){
                $list[$sid]['sdate'] = date('Y-m-d',strtotime($val['addtime']));
            }
            $list[$sid]['edate'] = date('Y-m-d',strtotime($val['addtime']));
            $list[$sid]['dealNum'] += $val['num'];
            $list[$sid]['chMoney'] += round(($val['avg_price']-$val['hold_avg_price'])*$val['num'],2);
        }
        $data = [];
        foreach ($list as $val){
            $data[] = $val;
        }
        $this->outData['data'] = $data;
        return $this->fjson($this->outData);
    }
    //历史交易详情
    public function historyInfo(){
//        $this->param['openId'] = 'o21vjJEJjN61Nz';
//        $this->param['token'] = sha1(md5('o21vjJEJjN61Nzhje11shkeo479'));
//        $this->param['sdate'] = '2017-12-1';
//        $this->param['edate'] = '2018-12-1';
//        $this->param['sid'] = 3;
        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'sid'=>array('msg'=>'sid参数异常','type'=>'int'),
            'sdate'=>array('msg'=>'sdate参数异常','type'=>'str'),
            'edate'=>array('msg'=>'edate参数异常','type'=>'str'),
            'token'=>array('msg'=>'token参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        $this->regToken($this->param['token'],$this->param['openId']);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }
        $sid = $this->param['sid'];
        $sModel = new StockModel();
        $sRes = $sModel->findData(['id'=>$sid]);
        $tdhModel = new TradeDealhistoryModel();
        $tdhList = $tdhModel->queryData(['AND'=>['sid'=>$sid,'addtime[>=]'=>$this->param['sdate'],'addtime[<=]'=>$this->param['edate'],'OR'=>['buy_uid'=>$uid,'sale_uid'=>$uid]]]);
        $cData = $sData = [];
        $cData['sno'] = $sRes['stock_no'];
        $cData['sname'] = $sRes['stock_name'];
        $totalHandMoney = $totalSaleMoney = $totalSaleNum = 0;
        $sdate = $edate = '';
        foreach ($tdhList as $val){
            $arr = [];
            $arr['isbuy'] = $val['buy_uid']==$uid ? 1 : 2;
            $arr['date'] = date('Y-m-d',strtotime($val['addtime']));
            $arr['price'] = $val['avg_price'];
            $arr['num'] = $val['num'];
            $sData[] = $arr;

            if(!$sdate){
                $sdate = date('Y-m-d',strtotime($val['addtime']));
            }
            $edate = date('Y-m-d',strtotime($val['addtime']));
            if($val['sale_uid']==$uid){
                $totalHandMoney += round($totalHandMoney+($val['hold_avg_price']*$val['num']),2);
                $totalSaleMoney += round($totalSaleMoney+($val['avg_price']*$val['num']),2);
                $totalSaleNum += $val['num'];
            }
        }
        $cData['buyAvgPrice'] = $totalSaleNum ? round($totalHandMoney/$totalSaleNum,2) : 0;
        $cData['saleAvgPrice'] = $totalSaleNum ? round($totalSaleMoney/$totalSaleNum,2) : 0;
        $cData['saleTotalNum'] = $totalSaleNum;
        $cData['chMoney'] = round($totalSaleMoney-$totalHandMoney,2);
        $cData['sdate'] = $sdate;
        $cData['edate'] = $edate;
        $this->outData['cData'] = $cData;
        $this->outData['sData'] = $sData;
        return $this->fjson($this->outData);
    }

    /*交易*/
    //所有股票数据
    public function allStock(){
        $sModel = new StockModel();
        $sList = $sModel->queryData(['status'=>1],['id','stock_name','stock_no']);
        $this->outData['data'] = $sList;
        return $this->fjson($this->outData);
    }
    //买入
    public function buy(){
//        $this->param['openId'] = 'o21vjJEJjN61Nz';
//        $this->param['sid'] = 1;
//        $this->param['quanlity'] = 1;
//        $this->param['price'] = 14.5;
//        $this->param['token'] = '65098444d7cc96b196e9b930df90970775bac991';
        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'sid'=>array('msg'=>'sid参数异常','type'=>'int'),
            'quanlity'=>array('msg'=>'quanlity参数异常','type'=>'int'),
            'price'=>array('msg'=>'price参数异常','type'=>'float'),
            'token'=>array('msg'=>'token参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        $this->regToken($this->param['token'],$this->param['openId']);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }

        //验证股票开市时间,价格是否合理
        $sModel = new StockModel();
        $tcheres = $sModel->stockTradeCheck($this->param['sid'],$this->param['price']);
        if($tcheres['code']){
            return $this->fjson($tcheres);
        }

        $this->redis = new Redis();
        $lockKey = LOCK_USER_BALANCE.$uid;
        if(!$this->redis->getLock($lockKey)){
            return $this->fjson(['code'=>1,'msg'=>'请求失败，请重试']);
        }
        //验证用户资金是否充足
        $payMoney = round($this->param['quanlity']*$this->param['price'],2);
        $uaModel = new UserAssetsModel();
        $raRes = $uaModel->reduceAssets($uid,$payMoney,BALANCE_MONEY,BALANCE_ENABLE,'交易委托');
        if(!$raRes){
            $this->redis->removeLock($lockKey);
            return $this->fjson(['code'=>1,'msg'=>'资金不足']);
        }

        //查询可成交委托的数据
        $loopBool = true;
        $canDealNum = 0;
        $dealData = [];
        while($loopBool){
            $this->redis->getLockEnabel(USER_STOCK_SALE_RKEY.$this->param['sid']);
            $zrange = $this->redis->client->zrange(USER_STOCK_SALE.$this->param['sid'],0,0,['withscores'=>true]);
            if($zrange){
                foreach ($zrange as $key=>$val){
                    $price = $key;
                }
                if($price>$this->param['price']){
                    $loopBool = false;
                }else{
                    $priceJson = $this->redis->client->get(USER_STOCK_SALE_PRIICE.$this->param['sid'].'_'.$price);
                    if(!$priceJson){
                        $loopBool = false;
                    }else{
                        $priceArr = json_decode($priceJson,true);
                        array_multisort(array_column($priceArr,'time'),SORT_ASC,$priceArr);

                        $oriPriceArr = $priceArr;
                        foreach ($priceArr as $key=>$darr){
                            if($loopBool){
                                $dealData[] = $darr;
                                $canDealNum += $darr['dnum'];
                                if($canDealNum>=$this->param['quanlity']){
                                    $loopBool = false;
                                    if($canDealNum>$this->param['quanlity']){
                                        $tdLeftNum = $darr['dnum']-($this->param['quanlity']-($canDealNum-$darr['dnum']));
                                        $oriPriceArr[$key]['dnum'] = $tdLeftNum;
                                    }else{
                                        unset($oriPriceArr[$key]);
                                    }
                                }else{
                                    unset($oriPriceArr[$key]);
                                }
                            }
                        }
                        if($oriPriceArr){
                            $this->redis->client->set(USER_STOCK_SALE_PRIICE.$this->param['sid'].'_'.$price,json_encode($oriPriceArr));
                        }else{
                            $this->redis->client->zremrangebyrank(USER_STOCK_SALE.$this->param['sid'],0,0);
                            $this->redis->client->del([USER_STOCK_SALE_PRIICE.$this->param['sid'].'_'.$price]);
                        }
                    }
                }
            }else{
                $loopBool = false;
            }
            $this->redis->removeLock(USER_STOCK_SALE_RKEY.$this->param['sid']);
        }

        //增加委托记录
        $tdgModel = new TradeDelegateHistoryModel();
        $btdgid = $tdgModel->addDelegate($uid,$this->param['sid'],TRADE_BUY,$this->param['quanlity'],$this->param['price']);
        $tdhModel = new TradeDealhistoryModel();
        //增加成交记录
        $noDealNum = $this->param['quanlity'];
        $wpNum = 0;
        foreach ($dealData as $val){
            if($val['dnum']>=$noDealNum){
                $dealNum = $noDealNum;
                $noDealNum = 0;
            }else{
                $dealNum = $val['dnum'];
                $noDealNum -= $dealNum;
            }
            $dhdata = [
                'deal_no'=>date('ymdHis').rand(1000,9999),
                'sid'=>$this->param['sid'],
                'buy_uid'=>$uid,
                'buy_delegateid'=>$btdgid,
                'sale_uid'=>$val['uid'],
                'sale_delegateid'=>$val['did'],
                'num'=>$dealNum,
                'avg_price'=>$this->param['price'],
                'price'=>round($this->param['price']*$dealNum),
                'fee'=>round($this->param['price']*$dealNum*$tcheres['tradeFee']/1000,2),
                'hold_avg_price'=>$val['avgprice'],
                'addtime'=>$this->timeNow
            ];
            $tdhModel->insertData($dhdata);
            //处理卖方数据（增加余额，扣减委托记录）
            $getMoney = round($dhdata['price']-$dhdata['fee'],2);
            $uaModel->addAssets($val['uid'],$getMoney,BALANCE_MONEY,BALANCE_ENABLE,'卖出成交');
            $tdgModel->editData(['id'=>$val['did']],['deal_num[+]'=>$dealNum,'left_num[-]'=>$dealNum]);
            if($val['avgprice']<$this->param['price']){
                $wpNum += $dealNum;
            }
        }

        //更新买方股票数据（持仓及记录，委托记录，redis记录）
        $doneNum = $this->param['quanlity']-$noDealNum;
        $tdgModel->editData(['id'=>$btdgid],['deal_num'=>$doneNum,'left_num'=>$noDealNum]);
        $tuaModel = new TradeUserAssetModel();
        $tuaModel->editUserHold($uid,$this->param['sid'],$doneNum,$this->param['price'],'委托买入');
        //redis存储记录
        if($noDealNum>0){
            $this->redis->getLockEnabel(USER_STOCK_BUY_RKEY.$this->param['sid']);
            $this->redis->client->zadd(USER_STOCK_BUY.$this->param['sid'],$this->param['price'],$this->param['price']);
            $priceJson = $this->redis->client->get(USER_STOCK_BUY_PRIICE.$this->param['sid'].'_'.$this->param['price']);
            if($priceJson){
                $dginfo = json_decode($priceJson,true);
            }
            $dginfo[] = ['did'=>$btdgid,'dnum'=>$noDealNum,'uid'=>$uid,'avgprice'=>$this->param['price'],'time'=>$this->mstime()];
            $this->redis->client->set(USER_STOCK_BUY_PRIICE.$this->param['sid'].'_'.$this->param['price'],json_encode($dginfo));
            $this->redis->removeLock(USER_STOCK_BUY_RKEY.$this->param['sid']);
        }

        //推送任务（更新盘口数据，更新K线图(股票，综合指数)，推送数据）
        $task = new Task();
        $sendData = [
            'sid'=>$this->param['sid'],
            'odealPrice'=>$this->param['price'],
            'dealPrice'=>$this->param['price'],
            'dealAvgPrice'=>$this->param['price'],
            'dealNum'=>$doneNum,
            'npNum'=>0,
            'wpNum'=>$wpNum,
            'minPrice'=>$this->param['price'],
            'maxPrice'=>$this->param['price'],
        ];
        $sdp = ['param'=>$sendData,'taskName'=>'tradeData'];
        $task->send($sdp);

        $this->redis->removeLock($lockKey);
        $this->outData['msg'] = '委托成功';
        return $this->fjson($this->outData);
    }
    //卖出
    public function sale(){
//        $this->param['openId'] = 'o21vjJEJjN61Nz';
//        $this->param['sid'] = 1;
//        $this->param['quanlity'] = 15;
//        $this->param['price'] = 14.5;
//        $this->param['token'] = '65098444d7cc96b196e9b930df90970775bac991';

        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'sid'=>array('msg'=>'sid参数异常','type'=>'int'),
            'quanlity'=>array('msg'=>'quanlity参数异常','type'=>'int'),
            'price'=>array('msg'=>'price参数异常','type'=>'float'),
            'token'=>array('msg'=>'token参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        $this->regToken($this->param['token'],$this->param['openId']);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }

        //验证股票开市时间,价格是否合理
        $sModel = new StockModel();
        $tcheres = $sModel->stockTradeCheck($this->param['sid'],$this->param['price']);
        if($tcheres['code']){
            return $this->fjson($tcheres);
        }

        $this->redis = new Redis();
        $lockKey = LOCK_USER_BALANCE.$uid;
        if(!$this->redis->getLock($lockKey)){
            return $this->fjson(['code'=>1,'msg'=>'请求失败，请重试']);
        }
        //验证用户股票是否充足
        $tuaModel = new TradeUserAssetModel();
        $raRes = $tuaModel->dgTrade($uid,$this->param['sid'],$this->param['quanlity'],'委托卖出');
        if($raRes['code']){
            $this->redis->removeLock($lockKey);
            return $this->fjson(['code'=>1,'msg'=>'持仓不足']);
        }

        //查询可成交委托的数据
        $loopBool = true;
        $canDealNum = 0;
        $dealData = [];
        while($loopBool){
            $this->redis->getLockEnabel(USER_STOCK_BUY_RKEY.$this->param['sid']);
            $zrange = $this->redis->client->zrevrange(USER_STOCK_BUY.$this->param['sid'],0,0,['withscores'=>true]);
            if($zrange){
                foreach ($zrange as $key=>$val){
                    $price = $key;
                }
                if($price<$this->param['price']){
                    $loopBool = false;
                }else{
                    $priceJson = $this->redis->client->get(USER_STOCK_BUY_PRIICE.$this->param['sid'].'_'.$price);
                    if(!$priceJson){
                        $loopBool = false;
                    }else{
                        $priceArr = json_decode($priceJson,true);
                        array_multisort(array_column($priceArr,'time'),SORT_ASC,$priceArr);

                        $oriPriceArr = $priceArr;
                        foreach ($priceArr as $key=>$darr){
                            if($loopBool){
                                $dealData[] = $darr;
                                $canDealNum += $darr['dnum'];
                                if($canDealNum>=$this->param['quanlity']){
                                    $loopBool = false;
                                    if($canDealNum>$this->param['quanlity']){
                                        $tdLeftNum = $darr['dnum']-($this->param['quanlity']-($canDealNum-$darr['dnum']));
                                        $oriPriceArr[$key]['dnum'] = $tdLeftNum;
                                    }else{
                                        unset($oriPriceArr[$key]);
                                    }
                                }else{
                                    unset($oriPriceArr[$key]);
                                }
                            }
                        }
                        if($oriPriceArr){
                            $this->redis->client->set(USER_STOCK_BUY_PRIICE.$this->param['sid'].'_'.$price,json_encode($oriPriceArr));
                        }else{
                            $this->redis->client->zremrangebyrank(USER_STOCK_BUY.$this->param['sid'],-1,-1);
                            $this->redis->client->del([USER_STOCK_BUY_PRIICE.$this->param['sid'].'_'.$price]);
                        }
                    }
                }
            }else{
                $loopBool = false;
            }
            $this->redis->removeLock(USER_STOCK_BUY_RKEY.$this->param['sid']);
        }

        //增加委托记录
        $tdgModel = new TradeDelegateHistoryModel();
        $btdgid = $tdgModel->addDelegate($uid,$this->param['sid'],TRADE_SALE,$this->param['quanlity'],$this->param['price'],$raRes['holdAvgPrice']);
        $tdhModel = new TradeDealhistoryModel();
        $tuaModel = new TradeUserAssetModel();

        //增加成交记录
        $noDealNum = $this->param['quanlity'];
        $saleTotalMoney = $saleTotalFee = 0;
        $saleTotalNum = 0;
        $odealPrice = $dealPrice = 0;
        $i = 0;
        $npNum = 0;
        foreach ($dealData as $val){
            if($i==0){
                $odealPrice = $val['avgprice'];
            }
            $dealPrice = $val['avgprice'];

            if($val['dnum']>=$noDealNum){
                $dealNum = $noDealNum;
                $noDealNum = 0;
            }else{
                $dealNum = $val['dnum'];
                $noDealNum -= $dealNum;
            }
            $saleMoney = round($val['avgprice']*$dealNum);
            $fee = round($saleMoney*$tcheres['tradeFee']/1000,2);
            $dhdata = [
                'deal_no'=>date('ymdHis').rand(1000,9999),
                'sid'=>$this->param['sid'],
                'buy_uid'=>$val['uid'],
                'buy_delegateid'=>$val['did'],
                'sale_uid'=>$uid,
                'sale_delegateid'=>$btdgid,
                'num'=>$dealNum,
                'avg_price'=>$val['avgprice'],
                'price'=>$saleMoney,
                'fee'=>$fee,
                'hold_avg_price'=>$raRes['holdAvgPrice'],
                'addtime'=>$this->timeNow
            ];
            $tdhModel->insertData($dhdata);

            //处理买方数据（增加持仓及记录，更新委托记录）
            $tdgModel->editData(['id'=>$val['did']],['deal_num[+]'=>$dealNum,'left_num[-]'=>$dealNum]);
            $tuaModel->editUserHold($val['uid'],$this->param['sid'],$dealNum,$val['avgprice'],'委托买入');
            $saleTotalMoney += $saleMoney-$fee;
            $saleTotalFee += $fee;
            $saleTotalNum += $dealNum;
            if($val['avgprice']>$this->param['price']){
                $npNum += $dealNum;
            }
            $i++;
        }

        //处理卖方数据（增加余额，扣减委托记录）
        if($saleTotalMoney>0){
            $uaModel = new UserAssetsModel();
            $uaModel->addAssets($uid,$saleTotalMoney,BALANCE_MONEY,BALANCE_ENABLE,'卖出成交');
        }
        $tdgModel->editData(['id'=>$btdgid],['deal_num[+]'=>$saleTotalNum,'left_num[-]'=>$saleTotalNum]);
        //redis存储记录
        if($noDealNum>0){
            $this->redis->getLockEnabel(USER_STOCK_SALE_RKEY.$this->param['sid']);
            $this->redis->client->zadd(USER_STOCK_SALE.$this->param['sid'],$this->param['price'],$this->param['price']);
            $priceJson = $this->redis->client->get(USER_STOCK_SALE_PRIICE.$this->param['sid'].'_'.$this->param['price']);
            if($priceJson){
                $dginfo = json_decode($priceJson,true);
            }
            $dginfo[] = ['did'=>$btdgid,'dnum'=>$noDealNum,'uid'=>$uid,'avgprice'=>$this->param['price'],'time'=>$this->mstime()];
            $this->redis->client->set(USER_STOCK_SALE_PRIICE.$this->param['sid'].'_'.$this->param['price'],json_encode($dginfo));
            $this->redis->removeLock(USER_STOCK_SALE_RKEY.$this->param['sid']);
        }

        //推送任务（更新盘口数据，更新K线图(股票，综合指数)，推送数据）
        $task = new Task();
        $sendData = [
            'sid'=>$this->param['sid'],
            'odealPrice'=>$odealPrice,
            'dealPrice'=>$dealPrice,
            'dealAvgPrice'=>$saleTotalNum ? round(($saleTotalMoney+$saleTotalFee)/$saleTotalNum,2) : 0,
            'dealNum'=>$saleTotalNum,
            'npNum'=>$npNum,
            'wpNum'=>0,
            'minPrice'=>$dealPrice,
            'maxPrice'=>$odealPrice,
        ];
        $sdp = ['param'=>$sendData,'taskName'=>'tradeData'];
        $task->send($sdp);

        $this->redis->removeLock($lockKey);
        $this->outData['msg'] = '委托成功';
        return $this->fjson($this->outData);
    }
    //委托列表（当前所有委托列表）
    public function delegateList(){
//        $this->param['openId'] = 'o21vjJEJjN61Nz';
//        $this->param['token'] = sha1(md5('o21vjJEJjN61Nzhje11shkeo479'));
        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'token'=>array('msg'=>'token参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        $this->regToken($this->param['token'],$this->param['openId']);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }
        $tdgModel = new TradeDelegateHistoryModel();
        $tdgQuery = $tdgModel->queryData(['uid'=>$uid,'left_num[>]'=>0]);
        $sidArr = [];
        foreach ($tdgQuery as $val){
            $sidArr[] = $val['sid'];
        }
        $sRes = [];
        if($sidArr){
            $sModel = new StockModel();
            $sQuery = $sModel->queryData(['id'=>$sidArr],['id','stock_no','stock_name']);
            foreach ($sQuery as $val){
                $sRes[$val['id']] = $val;
            }
        }
        $data = [];
        foreach ($tdgQuery as $val){
            $arr = [];
            $arr['did'] = $val['id'];
            $arr['sid'] = $val['sid'];
            $arr['type'] = $val['type'];
            $arr['delegateNum'] = $val['delegate_num'];
            $arr['delegatePrice'] = $val['delegate_price'];
            $arr['dealNum'] = $val['deal_num'];
            $arr['addtime'] = date('H:i:s',strtotime($val['addtime']));
            $arr['sname'] = $sRes[$val['sid']]['stock_name'];
            $arr['sno'] = $sRes[$val['sid']]['stock_no'];
            $data[] = $arr;
        }
        $this->outData['data'] = $data;
        return $this->fjson($this->outData);
    }
    //撤单列表(当日已撤委托列表)
    public function cancleList(){
//        $this->param['openId'] = 'o21vjJEJjN61Nz';
//        $this->param['token'] = sha1(md5('o21vjJEJjN61Nzhje11shkeo479'));
        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'token'=>array('msg'=>'token参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        $this->regToken($this->param['token'],$this->param['openId']);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }
        $tdgModel = new TradeDelegateHistoryModel();
        $tdgQuery = $tdgModel->queryData(['uid'=>$uid,'left_num'=>0,'deal_num[<]delegate_num','addtime[>=]'=>date('Y-m-d'),'addtime[<=]'=>date('Y-m-d H:i:s')]);
        $sidArr = [];
        foreach ($tdgQuery as $val){
            $sidArr[] = $val['sid'];
        }
        $sRes = [];
        if($sidArr){
            $sModel = new StockModel();
            $sQuery = $sModel->queryData(['id'=>$sidArr],['id','stock_no','stock_name']);
            foreach ($sQuery as $val){
                $sRes[$val['id']] = $val;
            }
        }
        $data = [];
        foreach ($tdgQuery as $val){
            $arr = [];
            $arr['sid'] = $val['sid'];
            $arr['type'] = $val['type'];
            $arr['delegateNum'] = $val['delegate_num'];
            $arr['delegatePrice'] = $val['delegate_price'];
            $arr['dealNum'] = $val['deal_num'];
            $arr['addtime'] = date('H:i:s',strtotime($val['addtime']));
            $arr['sname'] = $sRes[$val['sid']]['stock_name'];
            $arr['sno'] = $sRes[$val['sid']]['stock_no'];
            $data[] = $arr;
        }
        $this->outData['data'] = $data;
        return $this->fjson($this->outData);
    }
    //成交列表（当日成交列表）
    public function dealList(){
//        $this->param['openId'] = 'o21vjJEJjN61Nz';
//        $this->param['token'] = sha1(md5('o21vjJEJjN61Nzhje11shkeo479'));
        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'token'=>array('msg'=>'token参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        $this->regToken($this->param['token'],$this->param['openId']);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }

        $tdhModel = new TradeDealhistoryModel();
        $tdhQuery = $tdhModel->queryData(['AND'=>['addtime[>=]'=>date('Y-m-d'),'addtime[<=]'=>date('Y-m-d H:i:s'),'OR'=>['buy_uid'=>$uid,'sale_uid'=>$uid]]]);
        $sidArr = [];
        foreach ($tdhQuery as $val){
            $sidArr[] = $val['sid'];
        }
        $sRes = [];
        if($sidArr){
            $sModel = new StockModel();
            $sQuery = $sModel->queryData(['id'=>$sidArr],['id','stock_no','stock_name']);
            foreach ($sQuery as $val){
                $sRes[$val['id']] = $val;
            }
        }
        $data = [];
        foreach ($tdhQuery as $val){
            $arr = [];
            $arr['did'] = $val['id'];
            $arr['sid'] = $val['sid'];
            $arr['type'] = $val['buy_uid']==$uid ? 1 : 2;
            $arr['dealPrice'] = $val['avg_price'];
            $arr['dealNum'] = $val['num'];
            $arr['addtime'] = date('H:i:s',strtotime($val['addtime']));
            $arr['sname'] = $sRes[$val['sid']]['stock_name'];
            $arr['sno'] = $sRes[$val['sid']]['stock_no'];
            $data[] = $arr;
        }
        $this->outData['data'] = $data;
        return $this->fjson($this->outData);
    }
    //成交详情
    public function dealInfo(){
//        $this->param['openId'] = 'o21vjJEJjN61Nz';
//        $this->param['did'] = 6;
//        $this->param['sid'] = 1;
        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'did'=>array('msg'=>'did参数异常','type'=>'str'),
            'sid'=>array('msg'=>'sid参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }

        $sModel = new StockModel();
        $sRes = $sModel->findData(['id'=>$this->param['sid']]);
        $tdhModel = new TradeDealhistoryModel();
        $tdhRes = $tdhModel->findData(['id'=>$this->param['did']]);
        $data['type'] = $tdhRes['buy_uid']==$uid ? 1 : 2;
        $data['sname'] = $sRes['stock_name'];
        $data['sno'] = $sRes['stock_no'];
        $data['dealPrice'] = $tdhRes['avg_price'];
        $data['dealNum'] = $tdhRes['num'];
        $data['dealTotalMoney'] = $tdhRes['price'];
        $data['addtime'] = $tdhRes['addtime'];
        $data['dealId'] = $tdhRes['id'];
        $data['dealNo'] = $tdhRes['deal_no'];
        $tpModel = new TradePlaceModel();
        $tpRes = $tpModel->findData(['id'=>$sRes['tpid']]);
        $data['placeName'] = $tpRes['name'];
        $this->outData['data'] = $data;
        return $this->fjson($this->outData);

    }
    //撤单
    public function cancle(){
        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'did'=>array('msg'=>'did参数异常','type'=>'int'),
            'token'=>array('msg'=>'token参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        $this->regToken($this->param['token'],$this->param['openId']);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }
        $tdgModel = new TradeDelegateHistoryModel();
        $tdgRes = $tdgModel->findData(['id'=>$this->param['did'],'left_num[>]'=>0]);
        if(!$tdgRes){
            return $this->fjson(['code'=>0,'msg'=>'刷新后重试']);
        }
        $sid = $tdgRes['sid'];
        $price = round($tdgRes['delegate_price'],2);
        $this->redis = new Redis();
        if($tdgRes['type'] == 1){//买
            $this->redis->getLockEnabel(USER_STOCK_SALE_RKEY.$sid);
            $priceJson = $this->redis->client->get(USER_STOCK_BUY_PRIICE.$sid.'_'.$price);
            $myDelegate=$otherDelegate=[];
            if($priceJson){
                $priceArr = json_decode($priceJson,true);
                foreach ($priceArr as $darr){
                    if($darr['did'] == $this->param['did']){
                        $myDelegate = $darr;
                    }else{
                        $otherDelegate[] = $darr;
                    }
                }
            }
            $leftNum = $myDelegate['dnum'];
            $buyAvgPrice = $myDelegate['avgprice'];
            $rbackMoney = round($leftNum*$buyAvgPrice,2);
            //更新表
            if(!$otherDelegate){
                //删除
                $delKeya = USER_STOCK_BUY_PRIICE.$sid.'_'.$price;
                $delKeyb = USER_STOCK_BUY.$sid;
                $this->redis->client->del([$delKeya]);
                $this->redis->client->zrem($delKeyb,$price);
            }else{
                $this->redis->client->set(USER_STOCK_BUY_PRIICE.$sid.'_'.$price,json_encode($otherDelegate));
            }
            $tdgModel->editData(['id'=>$this->param['did']],['left_num'=>0]);
            //退还用户资金
            $uaModel = new UserAssetsModel();
            $uaModel->addAssets($uid,$rbackMoney,BALANCE_MONEY,BALANCE_ENABLE,'撤销买入');
            $this->redis->removeLock(USER_STOCK_SALE_RKEY.$sid);
        }elseif($tdgRes['type'] == 2){//卖
            $this->redis->getLockEnabel(USER_STOCK_BUY_RKEY.$sid);
            $priceJson = $this->redis->client->get(USER_STOCK_SALE_PRIICE.$sid.'_'.$price);
            $myDelegate=$otherDelegate=[];
            if($priceJson){
                $priceArr = json_decode($priceJson,true);
                foreach ($priceArr as $darr){
                    if($darr['did'] == $this->param['did']){
                        $myDelegate = $darr;
                    }else{
                        $otherDelegate[] = $darr;
                    }
                }
            }
            $rbackNum = $myDelegate['dnum'];
            //更新表
            if(!$otherDelegate){
                //删除
                $delKeya = USER_STOCK_SALE_PRIICE.$sid.'_'.$price;
                $delKeyb = USER_STOCK_SALE.$sid;
                $this->redis->client->del([$delKeya]);
                $this->redis->client->zrem($delKeyb,$price);
            }else{
                $this->redis->client->set(USER_STOCK_SALE_PRIICE.$sid.'_'.$price,json_encode($otherDelegate));
            }
            $tdgModel->editData(['id'=>$this->param['did']],['left_num'=>0]);
            //退还用户股票
            $tuaModel = new TradeUserAssetModel();
            $tuaModel->editUserHold($uid,$sid,$rbackNum,$price,'撤销卖出');
            $this->redis->removeLock(USER_STOCK_BUY_RKEY.$sid);
        }

        $stask = new Stask();
        $stask->sendFiveTradeData($sid);
        return $this->fjson($this->outData);
    }

    /*行情*/
    //市场页面(交易所)
    public function place(){
        $tpModel = new TradePlaceModel();
        $tpRes = $tpModel->queryData(['status'=>1],['id','name']);
        $this->outData['data'] = $tpRes;
        return $this->fjson($this->outData);
    }
    //交易所所有股票（股票id，股票名称，股票代码，当前价值，涨跌幅）
    public function placeStock(){
//        $this->param['tpId'] = 1;
        $needParam = array(
            'tpId'=>array('msg'=>'tpId参数异常','type'=>'int')
        );
        $this->regArguments($needParam,$this->param);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $sModel = new StockModel();
        $slist = $sModel->queryData(['tpid'=>$this->param['tpId'],'status'=>1]);
        $sidArr = [];
        foreach ($slist as $val){
            $sidArr[] = $val['id'];
        }
        $shRes = [];
        if($sidArr){
            $shModel = new StockHandicapModel();
            $shList = $shModel->queryData(['sid'=>$sidArr],['sid','new_price','zd_rang']);
            foreach ($shList as $val){
                $shRes[$val['sid']]['nowPrice'] = $val['new_price'];
                $shRes[$val['sid']]['zdRang'] = $val['zd_rang'];
            }
        }
        $data = ['up'=>[],'down'=>[]];
        foreach ($slist as $val){
            $arr = [];
            $arr['sid'] = $val['id'];
            $arr['sno'] = $val['stock_no'];
            $arr['sname'] = $val['stock_name'];
            $arr['nowPrice'] = $shRes[$val['id']]['nowPrice'];
            $arr['chPrice'] = $shRes[$val['id']]['nowPrice'] ? round($shRes[$val['id']]['nowPrice'] - ($shRes[$val['id']]['nowPrice']/(1+($shRes[$val['id']]['zdRang']/100))),2) : 0;
            $arr['zdRang'] = $shRes[$val['id']]['zdRang'].'%';
            if($shRes[$val['id']]['zdRang']>=0){
                $data['up'][] = $arr;
            }else{
                $data['down'][] = $arr;
            }
        }
        $this->outData['data'] = $data;
        return $this->fjson($this->outData);
    }
    //交易所综合指数折线图 当天的数据
    public function placeLine(){
        $needParam = array(
            'tpId'=>array('msg'=>'tpId参数异常','type'=>'int')
        );
        $this->regArguments($needParam,$this->param);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }

        $stime = date('Y-m-d');
        $tklModel = new TradeKlineModel();
        $tkQuery = $tklModel->queryData(['sid'=>$this->param['tpId'],'kline_type'=>KLINE_TYPE_MIN,'type'=>2,'edittime[>=]'=>$stime],['close','edittime']);
        $times = $prices = [];
        foreach ($tkQuery as $val){
            $times[]= date('H:i',strtotime($val['edittime']));
            $prices[] = $val['close'];
        }
        $data['times'] = $times;
        $data['prices'] = $prices;
        //交易所最新综合指数和涨跌幅
        $shModel = new StockHandicapModel();
        $newPrice = $shModel->compQuota($this->param['tpId']);
        $ytPrice = $tklModel->compytQuota($this->param['tpId']);
        $data['newPrice'] = $newPrice;
        $data['rang'] = round($ytPrice,2) ? round(($newPrice-$ytPrice)/$ytPrice*100,2).'%' : '0%';
        $data['isup'] = $newPrice>=$ytPrice ? 1 : 2;
        $this->outData['data'] = $data;
        return $this->fjson($this->outData);
    }
    //股票K线图(分时1，五日折线10，日2，周3，月4，年K线5)
    public function stockKline(){
//        $this->param['sid'] = 1;
//        $this->param['type'] = 1;
        $needParam = array(
            'sid'=>array('msg'=>'sid参数异常','type'=>'int'),
            'type'=>array('msg'=>'type参数异常','type'=>'int'),
        );
        $this->regArguments($needParam,$this->param);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        if($this->param['type'] == 1){
            //分时图
            $data = $this->hourLine($this->param['sid']);
        }elseif($this->param['type'] == 10){
            //五日分时图
            $data = $this->fdhourLine($this->param['sid']);
        }else{
            //K线图
            $data = $this->kline($this->param['sid'],$this->param['type']);
        }
        $this->outData['data'] = $data;
        return $this->fjson($this->outData);
    }
    protected function hourLine($sid){
        $stime = date('Y-m-d');
        $etime = date('Y-m-d',strtotime("+1 days"));
        $tklModel = new TradeKlineModel();
        $tkQuery = $tklModel->queryData(['sid'=>$sid,'kline_type'=>KLINE_TYPE_MIN,'type'=>1,'edittime[>=]'=>$stime,'edittime[<]'=>$etime],['close','edittime']);
        $times = $prices = [];
        foreach ($tkQuery as $val){
            $times[]= date('H:i',strtotime($val['edittime']));
            $prices[] = $val['close'];
        }
        $data['times'] = $times;
        $data['prices'] = $prices;
        return $data;
    }
    protected function fdhourLine($sid){
        $stime = date('Y-m-d',strtotime("-4 days"));
        $etime = date('Y-m-d',strtotime("+1 days"));
        $tklModel = new TradeKlineModel();
        $tkQuery = $tklModel->queryData(['sid'=>$sid,'kline_type'=>KLINE_TYPE_MIN,'type'=>1,'edittime[>=]'=>$stime,'edittime[<]'=>$etime],['close','edittime']);
        $times = $prices = [];
        foreach ($tkQuery as $val){
            $times[]= date('H:i',strtotime($val['edittime']));
            $prices[] = $val['close'];
        }
        $data['times'] = $times;
        $data['prices'] = $prices;
        return $data;
    }
    protected function kline($sid,$type){
        $where = [];
        $where['sid'] = $sid;
        $where['kline_type'] = $type;
        $where['type'] = 1;
        if($type==2){
            $where['edittime[>=]'] = date('Y-m-d',strtotime('-6 months'));
        }elseif($type==3){
            $where['edittime[>=]'] = date('Y-m-d',strtotime('-7 years'));
        }
        $tklModel = new TradeKlineModel();
        $tkQuery = $tklModel->queryData($where,['edittime','open','close','high','lower','deal_num']);
        $data=[];
        foreach ($tkQuery as &$val){
            $arr = [];
            $arr[] = date('Y-m-d',strtotime($val['edittime']));
            $arr[] = $val['open'];
            $arr[] = $val['close'];
            $arr[] = $val['high'];
            $arr[] = $val['lower'];
            $arr[] = $val['deal_num'];
            $data[]=$arr;
        }
        return $data;
    }

    //五档数据
    public function stockFiveData(){
//        $this->param['sid'] = 1;
        $needParam = array(
            'sid'=>array('msg'=>'sid参数异常','type'=>'int')
        );
        $this->regArguments($needParam,$this->param);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $this->redis = new Redis();
        $saleList = $this->redis->client->zrange(USER_STOCK_SALE.$this->param['sid'],0,4,['withscores'=>true]);
        $buyList = $this->redis->client->zrevrange(USER_STOCK_BUY.$this->param['sid'],0,4,['withscores'=>true]);
        $saleRes = $buyRes = [];
        $i = 1;
        foreach ($saleList as $key=>$val){
            $priceJson = $this->redis->client->get(USER_STOCK_SALE_PRIICE.$this->param['sid'].'_'.$key);
            $priceArr = $priceJson ? json_decode($priceJson,true) : [];
            $num = 0;
            foreach ($priceArr as $darr){
                $num += $darr['dnum'];
            }
            $arr = [];
            $arr['name'] = '卖'.$i;
            $arr['price'] = $key;
            $arr['num'] = $num;
            $i++;
            $saleRes[] = $arr;
        }
        for($i;$i<6;$i++){
            $arr = [];
            $arr['name'] = '卖'.$i;
            $arr['price'] = '--';
            $arr['num'] = '--';
            $saleRes[] = $arr;
        }


        $i = 1;
        foreach ($buyList as $key=>$val){
            $priceJson = $this->redis->client->get(USER_STOCK_BUY_PRIICE.$this->param['sid'].'_'.$key);
            $priceArr = $priceJson ? json_decode($priceJson,true) : [];
            $num = 0;
            foreach ($priceArr as $darr){
                $num += $darr['dnum'];
            }
            $arr = [];
            $arr['name'] = '买'.$i;
            $arr['price'] = $key;
            $arr['num'] = $num;
            $i++;
            $buyRes[] = $arr;
        }
        for($i;$i<6;$i++){
            $arr = [];
            $arr['name'] = '买'.$i;
            $arr['price'] = '--';
            $arr['num'] = '--';
            $buyRes[] = $arr;
        }
        $this->outData['buy'] = $buyRes;
        $this->outData['sale'] = $saleRes;
        return $this->fjson($this->outData);
    }
    //盘口数据
    public function stockHandicap(){
//        $this->param['sid'] = 1;
        $needParam = array(
            'sid'=>array('msg'=>'sid参数异常','type'=>'int'),
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
        );
        if(!$this->param['openId']){
            $this->param['openId'] = 0;
        }
        $this->regArguments($needParam,$this->param);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);

        $sModel = new StockModel();
        $tpModel = new TradePlaceModel();
        $sRes = $sModel->findData(['id'=>$this->param['sid']]);
        $tpRes = $tpModel->findData(['id'=>$sRes['tpid']]);
        $shModel = new StockHandicapModel();
        $rangPrice = $shModel->rangPrice($this->param['sid'],$tpRes['rang_space']);

        $shRes = $shModel->findData(['sid'=>$this->param['sid']]);
        $shRes['rang'] .= '%';
        $shRes['delegate_percent'] .= '%';
        $shRes['change_percent'] .= '%';
        $shRes['open_price'] = $shRes['open_price']!=0 ? $shRes['open_price'] : $rangPrice['minPrice'];
        $shRes['min_price'] = $rangPrice['minPrice'];
        $shRes['max_price'] = $rangPrice['maxPrice'];
        $shRes['ch_price'] = $shRes['new_price'] ? round($shRes['new_price'] - ($shRes['new_price']/(1+($shRes['zd_rang']/100))),2) : 0;
        $shRes['inSelf'] = 0;
        $shRes['zd_rang'] .= '%';
        if($uid){
            $myAllStock = $this->myAllStock($uid);
            if(in_array($this->param['sid'],$myAllStock)){
                $shRes['inSelf'] = 1;
            }
        }
        $this->outData['data'] = $shRes;
        return $this->fjson($this->outData);
    }
    //我的所有自选股id
    protected function myAllStock($uid){
        $ssModel = new SelfStockModel();
        $ssList = $ssModel->queryData(['uid'=>$uid],['sid']);
        $sidArr = [];
        foreach ($ssList as $val){
            $sidArr[] = $val['sid'];
        }
        return $sidArr;
    }
    //股票股东列表
    public function stockCompany(){
//                $this->param['sid'] = 1;
        $needParam = array(
            'sid'=>array('msg'=>'sid参数异常','type'=>'int')
        );
        $this->regArguments($needParam,$this->param);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $scModel = new StockCompanyModel();
        $scRes = $scModel->queryData(['sid'=>$this->param['sid']]);
        foreach ($scRes as &$val){
            $val['percent'] .= '%';
        }
        $this->outData['data'] = $scRes;
        return $this->fjson($this->outData);
    }
    //自选股页面
    public function selfStock(){
//        $this->param['openId'] = 'o21vjJEJjN61Nz';
        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
        );
        $this->regArguments($needParam,$this->param);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }
        $ssModel = new SelfStockModel();
        $ssList = $ssModel->queryData(['uid'=>$uid],['sid']);
        $sidArr = [];
        foreach ($ssList as $val){
            $sidArr[] = $val['sid'];
        }
        $data = [];
        if($sidArr){
            $sModel = new StockModel();
            $slist = $sModel->queryData(['id'=>$sidArr,'status'=>1]);
            $sRes = [];
            foreach ($slist as $val){
                $sRes[$val['id']] = $val;
            }
            $shRes = [];
            $shModel = new StockHandicapModel();
            $shList = $shModel->queryData(['sid'=>$sidArr],['sid','new_price','zd_rang']);
            foreach ($shList as $val){
                $shRes[$val['sid']]['nowPrice'] = $val['new_price'];
                $shRes[$val['sid']]['zdRang'] = $val['zd_rang'];
                $shRes[$val['sid']]['zdPrice'] = round($val['new_price'] - ($val['new_price']/(1+($val['zd_rang']/100))),2);
            }
            foreach ($ssList as $val){
                $arr = [];
                $sid = $val['sid'];
                $arr['sid'] = $sid;
                $arr['sno'] = $sRes[$sid]['stock_no'];
                $arr['sname'] = $sRes[$sid]['stock_name'];
                $arr['nowPrice'] = $shRes[$sid]['nowPrice'];
                $arr['zdRang'] = $shRes[$sid]['zdRang'].'%';
                $arr['zdPrice'] = $shRes[$sid]['zdPrice'];
                $data[] = $arr;
            }
        }
        $this->outData['data'] = $data;
        return $this->fjson($this->outData);
    }
    //添加自选股
    public function addSelfStock(){
        /*$this->param['openId'] = 'o21vjJEJjN61Nz';
        $this->param['sid'] = 1;
        $this->param['token'] = sha1(md5('o21vjJEJjN61Nzhje11shkeo479'));*/

        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'sid'=>array('msg'=>'sid参数异常','type'=>'int'),
            'token'=>array('msg'=>'token参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        $this->regToken($this->param['token'],$this->param['openId']);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }
        $ssModel = new SelfStockModel();
        $ssModel->iselfStock($uid,$this->param['sid']);
        return $this->fjson($this->outData);
    }
    //删除自选股
    public function delSelfStock(){
        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'sidArr'=>array('msg'=>'sidArr参数异常','type'=>'arr'),
            'token'=>array('msg'=>'token参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        $this->regToken($this->param['token'],$this->param['openId']);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }
        $ssModel = new SelfStockModel();
        foreach ($this->param['sidArr'] as $sid){
            $ssModel->delData(['uid'=>$uid,'sid'=>$sid]);
        }
        return $this->fjson($this->outData);
    }
    //自选股置顶
    public function sortSelfStock(){
//        $this->param['openId'] = 'o21vjJEJjN61Nz';
//        $this->param['sid'] = 1;
//        $this->param['token'] = sha1(md5('o21vjJEJjN61Nzhje11shkeo479'));
        $needParam = array(
            'openId'=>array('msg'=>'openId参数异常','type'=>'str'),
            'sidArr'=>array('msg'=>'sidArr参数异常','type'=>'arr'),
            'token'=>array('msg'=>'token参数异常','type'=>'str')
        );
        $this->regArguments($needParam,$this->param);
        $this->regToken($this->param['token'],$this->param['openId']);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $uModel = new UserModel();
        $uid = $uModel->getUidByOpenId($this->param['openId']);
        if(!$uid){
            return $this->fjson(['code'=>1,'msg'=>'账号异常，请联系客服人员']);
        }
        $ssModel = new SelfStockModel();
        foreach ($this->param['sidArr'] as $sid){
            $ssModel->sselfStock($uid,$sid);
        }
        return $this->fjson($this->outData);
    }

    //公告列表
    public function stockNotice(){
//        $this->param['sid'] = 1;
        $needParam = array(
            'sid'=>array('msg'=>'sid参数异常','type'=>'int')
        );
        $this->regArguments($needParam,$this->param);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $snModel = new StockNoticeModel();
        $snRes = $snModel->queryData(['sid'=>$this->param['sid'],'status'=>1],['id','title','addtime']);
        $this->outData['data'] = $snRes;
        return $this->fjson($this->outData);
    }
    //公告详情
    public function stockNoticeInfo(){
//        $this->param['snid'] = 1;
        $needParam = array(
            'snid'=>array('msg'=>'snid参数异常','type'=>'int')
        );
        $this->regArguments($needParam,$this->param);
        if($this->outData['code']){
            return $this->fjson($this->outData);
        }
        $snModel = new StockNoticeModel();
        $snRes = $snModel->queryData(['id'=>$this->param['snid']],['title','content','addtime']);
        $this->outData['data'] = $snRes;
        return $this->fjson($this->outData);
    }
}
